#!/usr/bin/env python
#
# Copyright 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

__author__ = 'scotty@google.com (Scotty Allen)'

import datetime
import logging
import model
import os
import sys
import wsgiref.handlers
import yaml

from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template

COLORS = ["#fff",
          "#ff7a7a",
          "#ffcc7a",
          "#fffa7a",
          "#81ff7a",
          "#7a99ff",
         ]

class MainPage(webapp.RequestHandler):
  def get(self):
    user = users.GetCurrentUser()
    is_logged_in = False
    if user:
      is_logged_in = True
    else:
      return self.show_login_page()

    template_values = {
      "is_logged_in": is_logged_in,
      "user": user,
      "logout_url": users.CreateLogoutURL("/"),
      "task_lists": model.TaskList.GetTaskListsForOwner(users.GetCurrentUser()),
      "colors": COLORS,
      "default_color": COLORS[0],
      "analytics_id": config.get("analytics_id"),
    }

    path = os.path.join(os.path.dirname(__file__), 'index.tpl')
    self.response.out.write(template.render(path, template_values))

  def show_login_page(self):
    template_values = {
      "login_url": users.CreateLoginURL("/"),
    }
    path = os.path.join(os.path.dirname(__file__), 'login.tpl')
    self.response.out.write(template.render(path, template_values))


class NewTask(webapp.RequestHandler):
  def post(self):
    task_list_key = db.Key.from_path('TaskList',
                                     int(self.request.params['task_list_id']))
    task_list = model.TaskList.get(task_list_key)
    if (task_list.owner != users.GetCurrentUser()):
      self.response.out.write('ERROR')
      return
    task = model.Task(title = self.request.params['title'],
                      task_list = task_list,
                      done = False)
    task.put()
    self.response.out.write(task.key().id())


class UpdateTask(webapp.RequestHandler):
  def post(self):
    params = self.request.params
    key = db.Key.from_path('Task',
                           int(params['id']))
    task = model.Task.get(key)
    if (task.task_list.owner != users.GetCurrentUser()):
      self.response.out.write('ERROR')
      return
    if ('done' in params):
      task.done = bool(int(params['done']))
    task.put()
    self.response.out.write("OK")


class NewTaskList(webapp.RequestHandler):
  def post(self):
    todone_user = model.ToDoneUser.GetOrCreateUser(users.GetCurrentUser())
    task_list = model.TaskList(name = self.request.params['name'],
                               color = self.request.params['color'],
                               owner = users.GetCurrentUser(),
                               todone_user = todone_user)

    task_list.put()
    self.response.out.write(task_list.key().id())


class UpdateTaskList(webapp.RequestHandler):
  def post(self):
    params = self.request.params
    key = db.Key.from_path('TaskList',
                           int(params['id']))
    task_list = model.TaskList.get(key)
    if (task_list.owner != users.GetCurrentUser()):
      self.response.out.write('ERROR')
      return
    if ('is_shown' in params):
      task_list.is_shown = bool(int(params['is_shown']))
    if ('name' in params):
      task_list.name = params['name']
    if ('color' in params):
      task_list.color = params['color']
    if ('is_completed_tasks_shown' in params):
      task_list.is_completed_tasks_shown = bool(int(
          params['is_completed_tasks_shown']))
    task_list.put()
    self.response.out.write("OK")


class DeleteTaskList(webapp.RequestHandler):
  def post(self):
    params = self.request.params
    key = db.Key.from_path('TaskList',
                           int(params['id']))
    task_list = model.TaskList.get(key)
    task_list.delete()
    self.response.out.write("OK")


class AdminPage(webapp.RequestHandler):
  def get(self):
    if not users.is_current_user_admin():
      self.response.out.write("Permission denied.")
      return
    limit = 10
    offset = 0
    task_lists = []
    if 'limit' in self.request.params and 'offset' in self.request.params:
      limit = int(self.request.params['limit'])
      offset = int(self.request.params['offset'])
      task_lists = model.TaskList.AddToDoneUsers(limit, offset)
      offset += limit
      
    template_values = {
      "limit": limit,
      "offset": offset,
      "user_count": model.ToDoneUser.Count(),
      "list_count": model.Counter.GetCounter("task_lists").value,
      "task_count": model.Counter.GetCounter("tasks").value,
      "task_lists": task_lists,
    }
    path = os.path.join(os.path.dirname(__file__), 'admin.tpl')
    self.response.out.write(template.render(path, template_values))


class RecountLists(webapp.RequestHandler):
  def get(self):
    year, month, day = [int(x) for x in self.request.params["date"].split('-')]
    hour = int(self.request.params["hour"])
    limit_hours = int(self.request.params["limit"])
    start = datetime.datetime(year, month, day, hour)
    end = start + datetime.timedelta(hours=limit_hours)

    list_count = db.GqlQuery("SELECT * FROM TaskList WHERE date_created > :1 "
                             "AND date_created < :2 LIMIT 1000",
                             start, end).count()
    list_counter = model.Counter.GetCounter("task_lists")
    list_counter.Increment(list_count)

    task_count = db.GqlQuery("SELECT * FROM Task WHERE date_created > :1 AND "
                             "date_created < :2 LIMIT 1000", start, end).count()
    task_counter = model.Counter.GetCounter("tasks")
    task_counter.Increment(task_count)

    template_values = {
        "limit": limit_hours,
        "list_count": list_count,
        "list_total": model.Counter.GetCounter("task_lists").value,
        "task_count": task_count,
        "task_total": model.Counter.GetCounter("tasks").value,
        "date": end
    }
    path = os.path.join(os.path.dirname(__file__), 'count.tpl')
    self.response.out.write(template.render(path, template_values))


class ClearCounts(webapp.RequestHandler):
  def get(self):
    model.Counter.GetCounter("tasks").Clear()
    model.Counter.GetCounter("task_lists").Clear()
    self.response.out.write("Cleared")


class ShowUserData(webapp.RequestHandler):
  def get(self):
    email = self.request.params["email"]
    user = users.User(email)
    lists = db.GqlQuery("SELECT * FROM TaskList WHERE owner = :1 ORDER BY "
                        "date_created", user)
    template_values = {
        "email": email,
        "lists": lists
    }
    path = os.path.join(os.path.dirname(__file__), 'show_user_data.tpl')
    self.response.out.write(template.render(path, template_values))


class Config:
  def __init__(self, filename):
    self.values = None
    if (os.path.exists(filename)):
      file = open(filename)
      self.values = yaml.load(file.read())
      sys.stderr.write(str(self.values))

  def get(self, key):
    if self.values:
      return self.values[key]
    else:
      return None


config = Config("config.yaml")
application = webapp.WSGIApplication([('/', MainPage),
                                      ('/task/new', NewTask),
                                      ('/task/update', UpdateTask),
                                      ('/task_list/new', NewTaskList),
                                      ('/task_list/update', UpdateTaskList),
                                      ('/task_list/delete', DeleteTaskList),
                                      ('/admin', AdminPage),
                                      ('/admin/recount_lists', RecountLists),
                                      ('/admin/clear_counts', ClearCounts),
                                      ('/admin/show_data', ShowUserData),
                                     ],
                                     debug=True)
wsgiref.handlers.CGIHandler().run(application)
